<template>
  <el-dialog
    v-model="dialogVisible"
    title="自然语言生成SQL"
    width="50%"
    :close-on-click-modal="false"
    :before-close="handleClose"
  >
    <div class="generate-dialog-content">
      <!-- 连接状态显示 -->
      <div class="connection-status" :class="{ connected: isConnected }">
        <el-icon class="status-icon"><Connection /></el-icon>
        {{ isConnected ? 'AI 服务已连接' : '正在连接 AI 服务...' }}
      </div>

      <div class="input-section">
        <div class="input-header">
          <span class="section-title">查询需求</span>
          <!-- 历史记录下拉菜单 -->
          <el-dropdown @command="handleHistorySelect" trigger="click">
            <el-button size="small" type="info" plain>
              <el-icon><Timer /></el-icon>
              历史记录
              <el-icon class="el-icon--right"><ArrowDown /></el-icon>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item 
                  v-for="(item, index) in historyList" 
                  :key="index" 
                  :command="item"
                >
                  <div class="history-item">
                    <span class="history-text">{{ truncateText(item.prompt, 50) }}</span>
                    <span class="history-time">{{ formatTime(item.timestamp) }}</span>
                    <el-icon 
                      class="delete-icon" 
                      @click.stop="deleteHistory(index)"
                    >
                      <Delete />
                    </el-icon>
                  </div>
                </el-dropdown-item>
                <el-dropdown-item v-if="!historyList.length" disabled>
                  暂无历史记录
                </el-dropdown-item>
                <el-dropdown-item 
                  v-if="historyList.length" 
                  divided
                  @click.stop="clearHistory"
                >
                  <el-icon><Delete /></el-icon>
                  清空历史
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>

        <el-input
          v-model="naturalLanguage"
          type="textarea"
          :rows="4"
          placeholder="请输入您的查询需求，例如：查询最近7天的订单数据，包含订单金额大于1000元的记录"
          :disabled="isGenerating || !isConnected"
        />
      </div>
      
      <!-- 思考过程 -->
      <div v-if="isGenerating || generatingText" class="result-section">
        <div class="result-info">
          <el-tag size="small" type="info">生成过程</el-tag>
        </div>
        <div class="reasoning-content" ref="reasoningContent" @scroll="handleScroll">
          <div v-text="generatingText"></div>
          
          <!-- 滚动到底部按钮 -->
          <div 
            v-show="showScrollButton" 
            class="scroll-bottom-button"
            @click="scrollToBottom('reasoning')"
          >
            <el-icon><Bottom /></el-icon>
          </div>
        </div>
      </div>

      <!-- 生成结果 -->
      <div v-if="generatedSQL" class="result-section">
        <div class="result-info">
          <el-tag size="small" type="success">生成的SQL</el-tag>
          <el-button-group>
            <el-button size="small" type="primary" @click="useGeneratedSQL">
              使用此SQL
            </el-button>
            <el-button size="small" @click="handleGenerate">
              重新生成
            </el-button>
          </el-button-group>
        </div>
        <div class="sql-content" ref="sqlContent">
          <pre><code>{{ generatedSQL }}</code></pre>
        </div>
      </div>

      <div class="dialog-footer">
        <el-button @click="handleClose" :disabled="isGenerating">
          取消
        </el-button>
        <el-button 
          type="primary" 
          @click="handleGenerate" 
          :loading="isGenerating"
          :disabled="!isConnected || !naturalLanguage"
        >
          生成SQL
        </el-button>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Connection, Timer, ArrowDown, Delete, Bottom } from '@element-plus/icons-vue'
import config from "@/config"

const props = defineProps({
  modelValue: Boolean,
})

const emit = defineEmits(['update:modelValue', 'generated'])

// 状态
const naturalLanguage = ref('')
const generatedSQL = ref('')
const generatingText = ref('')
const isGenerating = ref(false)
const isConnected = ref(false)
let ws = null
let reconnectAttempts = 0
const MAX_RECONNECT_ATTEMPTS = 3

// 历史记录
const historyList = ref([])
const MAX_HISTORY = 10

// 引用和状态
const reasoningContent = ref(null)
const showScrollButton = ref(false)
const isAutoScrolling = ref(true)

// 计算属性
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 初始化 WebSocket 连接
const initWebSocket = () => {
  if (ws?.readyState === WebSocket.OPEN) return

  try {
    ws = new WebSocket(config.AI_URL)

    ws.onopen = () => {
      console.log('WebSocket连接已建立')
      isConnected.value = true
      reconnectAttempts = 0
    }

    ws.onclose = () => {
      console.log('WebSocket连接已关闭')
      isConnected.value = false
      if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
        reconnectAttempts++
        setTimeout(initWebSocket, 1000 * reconnectAttempts)
      } else {
        ElMessage.error('AI 服务连接失败，请稍后重试')
      }
    }

    ws.onerror = (error) => {
      console.error('WebSocket错误:', error)
      isConnected.value = false
    }

    ws.onmessage = handleMessage
  } catch (error) {
    console.error('创建WebSocket连接错误:', error)
    isConnected.value = false
  }
}

// 从localStorage加载历史记录
const loadHistory = () => {
  try {
    const saved = localStorage.getItem('sqlGenerateHistory')
    if (saved) {
      historyList.value = JSON.parse(saved)
    }
  } catch (error) {
    console.error('加载历史记录失败:', error)
  }
}

// 保存历史记录到localStorage
const saveHistory = () => {
  try {
    localStorage.setItem('sqlGenerateHistory', JSON.stringify(historyList.value))
  } catch (error) {
    console.error('保存历史记录失败:', error)
  }
}

// 添加历史记录
const addHistory = (prompt, sql) => {
  // 检查是否已存在相同的记录
  const isDuplicate = historyList.value.some(item => 
    item.prompt === prompt && item.sql === sql
  )

  // 如果是重复记录，则不保存
  if (isDuplicate) {
    return
  }

  // 添加新记录
  historyList.value.unshift({
    prompt,
    sql,
    timestamp: new Date().toISOString()
  })
  
  // 限制历史记录数量
  if (historyList.value.length > MAX_HISTORY) {
    historyList.value = historyList.value.slice(0, MAX_HISTORY)
  }
  
  saveHistory()
}

// 删除单条历史记录
const deleteHistory = async (index) => {
  try {
    await ElMessageBox.confirm('确定要删除这条历史记录吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    historyList.value.splice(index, 1)
    saveHistory()
  } catch {
    // 用户取消删除
  }
}

// 清空历史记录
const clearHistory = async () => {
  try {
    await ElMessageBox.confirm('确定要清空所有历史记录吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    historyList.value = []
    saveHistory()
  } catch {
    // 用户取消清空
  }
}

// 选择历史记录
const handleHistorySelect = (item) => {
  naturalLanguage.value = item.prompt
  // 可以选择是否自动填充SQL
  // generatedSQL.value = item.sql
}

// 添加历史记录时间显示
const formatTime = (timestamp) => {
  const date = new Date(timestamp)
  return date.toLocaleString('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

// 截断文本
const truncateText = (text, length) => {
  return text.length > length ? text.slice(0, length) + '...' : text
}

// 处理滚动事件
const handleScroll = (event) => {
  const el = event.target
  const isBottom = Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) < 10
  showScrollButton.value = !isBottom
  isAutoScrolling.value = isBottom
}

// 滚动到底部
const scrollToBottom = async (type = 'reasoning') => {
  await nextTick()
  const container = type === 'reasoning' ? reasoningContent.value : null
  if (container) {
    container.scrollTop = container.scrollHeight
    isAutoScrolling.value = true
    showScrollButton.value = false
  }
}

// 修改消息处理函数，添加自动滚动
const handleMessage = (event) => {
  try {
    const data = JSON.parse(event.data)
    if (data.type === 'reply') {
      if (data.messageType === 'reasoning') {
        generatingText.value = (generatingText.value || '') + data.content
        // 如果启用了自动滚动，则滚动到底部
        if (isAutoScrolling.value) {
          scrollToBottom('reasoning')
        }
      } else if (data.messageType === 'content') {
        if (data.content) {
          generatingText.value = (generatingText.value || '') + data.content
          if (isAutoScrolling.value) {
            scrollToBottom('reasoning')
          }
        } else {
          // 生成完成时，从完整的内容中提取SQL
          const fullContent = generatingText.value
          if (fullContent) {
            // 尝试提取最后一个SQL代码块
            const sqlBlocks = fullContent.match(/```sql\n?([\s\S]*?)\n?```/g) ||
                            fullContent.match(/```\n?([\s\S]*?)\n?```/g)
            
            if (sqlBlocks) {
              // 获取最后一个SQL块
              const lastBlock = sqlBlocks[sqlBlocks.length - 1]
              const sqlMatch = lastBlock.match(/```(?:sql)?\n?([\s\S]*?)\n?```/)
              if (sqlMatch) {
                const sqlContent = sqlMatch[1]
                  .replace(/^[\s\n]+|[\s\n]+$/g, '')
                  .replace(/\n{3,}/g, '\n\n')
                
                generatedSQL.value = sqlContent
                // 生成完成时保存历史记录
                addHistory(naturalLanguage.value, sqlContent)
              }
            }
          }
          isGenerating.value = false
        }
      }
    }
  } catch (error) {
    console.error('处理消息错误:', error)
    handleError()
  }
}

// 生成SQL
const handleGenerate = () => {
  if (!naturalLanguage.value || !isConnected.value) return

  isGenerating.value = true
  generatingText.value = ''
  generatedSQL.value = ''

  const msg = {
    type: 'prompt',
    message: `请分析以下需求并生成对应的SQL查询语句，先说明分析思路，最后给出SQL语句：\n${naturalLanguage.value}`,
    mode: 'generate'
  }

  try {
    ws.send(JSON.stringify(msg))
  } catch (error) {
    console.error('发送消息错误:', error)
    handleError()
  }
}

// 使用生成的SQL
const useGeneratedSQL = () => {
  emit('generated', generatedSQL.value)
  handleClose()
}

// 错误处理
const handleError = () => {
  ElMessage.error('生成SQL失败，请重试')
  isGenerating.value = false
}

// 关闭对话框
const handleClose = () => {
  if (isGenerating.value) {
    ElMessage.warning('正在生成中，请等待完成或终止生成')
    return
  }
  naturalLanguage.value = ''
  generatedSQL.value = ''
  generatingText.value = ''
  dialogVisible.value = false
}

// 监听对话框显示状态
watch(() => props.modelValue, (newVal) => {
  if (newVal && !isConnected.value) {
    initWebSocket()
  }
})

// 组件挂载时初始化连接并加载历史记录
onMounted(() => {
  loadHistory()
  if (props.modelValue) {
    initWebSocket()
  }
})

// 组件卸载时清理
onUnmounted(() => {
  if (ws) {
    ws.close()
    ws = null
  }
})
</script>

<style scoped>
.generate-dialog-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
  height: 70vh;
  overflow-y: auto;
  scroll-behavior: smooth;
}

.result-section {
  margin-bottom: 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.1);
}

.result-info {
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.reasoning-content {
  position: relative;
  padding: 16px;
  color: #666;
  font-style: italic;
  white-space: pre-wrap;
  line-height: 1.6;
  background-color: #f8f9fa;
  border-radius: 0 0 4px 4px;
  height: 200px;
  overflow-y: auto;
  font-size: 14px;
  scroll-behavior: smooth;
}

.reasoning-content::-webkit-scrollbar {
  width: 6px;
}

.reasoning-content::-webkit-scrollbar-thumb {
  background-color: #dcdfe6;
  border-radius: 3px;
}

.reasoning-content::-webkit-scrollbar-track {
  background-color: transparent;
}

.scroll-bottom-button {
  position: absolute;
  right: 16px;
  bottom: 16px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: #fff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s;
  color: #909399;
  z-index: 1;
}

.scroll-bottom-button:hover {
  background-color: #f2f6fc;
  color: var(--el-color-primary);
  transform: translateY(-2px);
}

.scroll-bottom-button .el-icon {
  font-size: 18px;
}

.sql-content {
  padding: 16px;
  background-color: #f8f9fa;
  border-radius: 0 0 4px 4px;
  border: 1px solid #ebeef5;
  margin-top: 16px;
}

.sql-content pre {
  margin: 0;
  white-space: pre-wrap;
  font-family: 'Courier New', Consolas, monospace;
  line-height: 1.5;
  color: #333;
  font-size: 14px;
}

.sql-content code {
  display: block;
  padding: 8px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

:deep(.el-dialog__body) {
  padding-top: 20px;
}

.connection-status {
  padding: 10px 16px;
  margin: 0 0 16px;
  background-color: #fff3e6;
  color: #e6a23c;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  transition: all 0.3s ease;
}

.connection-status.connected {
  background-color: #f0f9eb;
  color: #67c23a;
}

.status-icon {
  animation: pulse 2s infinite;
}

.connected .status-icon {
  animation: none;
}

@keyframes pulse {
  0% { opacity: 0.6; }
  50% { opacity: 1; }
  100% { opacity: 0.6; }
}

.input-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.input-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.section-title {
  font-size: 14px;
  color: #606266;
  font-weight: 500;
}

.history-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding-right: 8px;
}

.history-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
}

.history-time {
  color: #909399;
  font-size: 12px;
  white-space: nowrap;
}

.delete-icon {
  opacity: 0;
  transition: opacity 0.2s;
  color: #f56c6c;
  cursor: pointer;
  font-size: 16px;
}

.history-item:hover .delete-icon {
  opacity: 1;
}

:deep(.el-dropdown-menu__item) {
  padding: 8px 16px;
  min-width: 240px;
}

:deep(.el-dropdown-menu__item.is-divided) {
  margin-top: 8px;
  border-top: 1px solid #ebeef5;
}

:deep(.el-dropdown-menu__item.is-disabled) {
  color: #909399;
}
</style> 